package com.intellif.mozping.mydbpool.semaphore;

import com.intellif.mozping.mydbpool.MyConnectionImpl;
import com.intellif.mozping.mydbpool.MyPool;

import java.sql.Connection;
import java.util.LinkedList;
import java.util.concurrent.Semaphore;

/**
 * @author by mozping
 * @Classname MyDbPool
 * @Description TODO
 * @Date 2019/2/26 17:18
 */
public class MyDbPoolSemaphore implements MyPool {

    private final static int POLL_SIZE = 20;
    //useful代表可用的数据库连接，useless代表已经被使用的数据库连接
    private final Semaphore useful, inuse;

    public MyDbPoolSemaphore() {
        this.useful = new Semaphore(POLL_SIZE);
        this.inuse = new Semaphore(0);
    }

    //真正存放连接对象的容器
    private static LinkedList<Connection> pool = new LinkedList<>();

    static {
        for (int i = 0; i < POLL_SIZE; i++) {
            pool.add(MyConnectionImpl.fetchConnection());
        }
    }


    public Connection getConnection() throws InterruptedException {
        useful.acquire();
        Connection conn;
        synchronized (pool) {
            conn = pool.removeFirst();
        }
        inuse.release();
        return conn;
    }

    @Override
    public Connection getConnection(long overtime) throws InterruptedException {
        if (overtime <= 0) {
            return getConnection();
        }
        synchronized (pool) {
            if (overtime < 0) {
                while (pool.isEmpty()) {
                    pool.wait();
                }
                return pool.removeFirst();
            } else {
                long end = System.currentTimeMillis() + overtime;
                long remain = overtime;
                while (pool.isEmpty() && remain > 0) {
                    pool.wait(remain);
                    remain = end - System.currentTimeMillis();
                }
                Connection conn = null;
                if (!pool.isEmpty()) {
                    conn = pool.removeFirst();
                }
                return conn;
            }
        }

    }

    @Override
    public void releaseConn(Connection connection) throws InterruptedException {

        if (connection != null) {
            System.out.println("当前有:"+useful.getQueueLength()+"个线程等待数据库连接! 可用连接数为"+useful.availablePermits());
            inuse.acquire();
            synchronized (pool) {
                pool.addLast(connection);
            }
            useful.release();
        }
    }
}
